package net.homelinux.chaoswg.io.renga.krypto.idea;

import java.awt.GridLayout;
import java.math.BigInteger;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import net.homelinux.chaoswg.io.renga.core.registries.GlobalPropertyRegistry;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.numerical.Unsigned32Bit;

public class IDEAMultStateChanger implements Runnable {
    JLabel firstOperandsDisplay;
    JLabel secondOperandsDisplay;
    JLabel resultDisplay;
    JFrame jw;
    
    final IDEAMultState initialState;
    
    public IDEAMultStateChanger (IDEAMultState initialState) {
        this.initialState = initialState;
        
        jw = new JFrame ("IDEA-Multiply");
        jw.getContentPane().add (getPanel());
        jw.setLocationRelativeTo(null);
        
        jw.setSize(500, 100);
    }
    
    public JPanel getPanel() {
        JPanel toReturn = new JPanel (new GridLayout (3,1));
        toReturn.add (firstOperandsDisplay = new JLabel (initialState.getFactor0().toString()));
        toReturn.add (secondOperandsDisplay = new JLabel (initialState.getFactor1().toString()));
        toReturn.add (resultDisplay = new JLabel (initialState.getResult().toString()));

        firstOperandsDisplay.setHorizontalAlignment(JLabel.RIGHT);
        secondOperandsDisplay.setHorizontalAlignment(JLabel.RIGHT);
        resultDisplay.setHorizontalAlignment(JLabel.RIGHT);

        return toReturn;
    }

    
    private void setNew () {
        firstOperandsDisplay.setText (initialState.getFactor0().toString());
        firstOperandsDisplay.paintImmediately(firstOperandsDisplay.getVisibleRect());
        secondOperandsDisplay.setText (initialState.getFactor1().toString());
        secondOperandsDisplay.paintImmediately(firstOperandsDisplay.getVisibleRect());
        resultDisplay.setText (initialState.getResult().toString());
        resultDisplay.paintImmediately(firstOperandsDisplay.getBounds());
    }

    public void run() {
        int delay = ((Integer)GlobalPropertyRegistry.getGlobalPropertyRegistry().getProperty("animationSpeed")) * 100;

        jw.setVisible(true);
        Unsigned32Bit factor0 = new Unsigned32Bit ( initialState.getFactor0().getValue());
        Unsigned32Bit factor1 = new Unsigned32Bit ( initialState.getFactor1().getValue());
        
        setNew();
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {System.err.println ("ERR");}
        
        if (factor0.getValue().equals(new BigInteger ("0"))) {
            factor0 = new Unsigned32Bit (new BigInteger ("65536"));
            
            initialState.setFactor0(factor0);
            setNew();
            try {
                Thread.sleep(delay);
            } catch (InterruptedException ie) {System.err.println ("ERR");}
        }
        
        if (factor1.getValue().equals(new BigInteger ("0"))) {
            factor1 = new Unsigned32Bit (new BigInteger ("65536"));

            initialState.setFactor0(factor1);
            setNew();
            try {
                Thread.sleep(delay);
            } catch (InterruptedException ie) {System.err.println ("ERR");}
        }
        
        BigInteger aVal = factor0.getValue();
        BigInteger bVal = factor1.getValue();
        BigInteger exp2_16 = new BigInteger ("65536");
        
        initialState.setResult(new Unsigned32Bit ( aVal.multiply (bVal).mod (exp2_16.add(new BigInteger ("1"))) )   );
        setNew();

        try {
            Thread.sleep(delay);
        } catch (InterruptedException ie) {}
        setNew();

        if (initialState.getResult().getValue().equals(new BigInteger ("65536"))) {
            Unsigned32Bit result = new Unsigned32Bit (new BigInteger ("0"));

            initialState.setResult(result);
            setNew();
            try {
                Thread.sleep(delay);
            } catch (InterruptedException ie) {System.err.println ("ERR");}
        }

    }
    
    public void close () {
        jw.dispose();
    }
}
